using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using Deepcode.Flux.Core.Systems.CMS;
using Deepcode.Flux.Core.Systems.CMS.TemplateGallery;

public partial class Private_CMS_main_actions : Deepcode.Flux.Core.UI.AdministrationModulePage
{
	#region Permission Code Override
	public override string RequiredPermissionCode { get { return "FluxCMSAccess"; } }
	#endregion
	#region ViewState and Properties
	/// <summary>
	/// Store the ID of the content passed to the actions
	/// </summary>
	protected int ContentID
	{
		get
		{
			object o = ViewState["CID"];
			if( o == null ) return -1;
			return (int) o;
		}
		set
		{
			ViewState["CID"] = value;
		}
	}
	#endregion
	#region Page Load Event
	/// <summary>
	/// Page Load event
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	protected void Page_Load(object sender, EventArgs e)
	{
		if (!Page.IsPostBack)
		{
			// Load path data
			ContentID = GetAttribute("ContentID", 0);

			// If no path passed in, user last known path from registry
			if (ContentID == 0)
				ContentID = UserSetting("CMSLASTPATH", -1);

			// Load the content information
			BindData();

			// See if we have a refresh event being passed in
			bool refreshFrames = (GetAttribute("refresh", "") != "");
			if( refreshFrames ) this.ReloadFrames();
		}
	}
	#endregion
	#region Page Init Event
	/// <summary>
	/// Page initialisation event
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	protected void Page_Init(object sender, EventArgs e)
	{
		actAddNew.Click += new EventHandler(actAddNew_Click);
		actEdit.Click += new EventHandler(actEdit_Click);
		actDelete.Click += new EventHandler(actDelete_Click);
		actCheckout.Click += new EventHandler(actCheckout_Click);
		actCheckin.Click += new EventHandler(actCheckin_Click);
		actSubmit.Click += new EventHandler(actSubmit_Click);
		actMoveUp.Click += new EventHandler(actMoveUp_Click);
		actMoveDown.Click += new EventHandler(actMoveDown_Click);
		actVersionHistory.Click += new EventHandler(actVersionHistory_Click);
		actCopy.Click += new EventHandler(actCopy_Click);
		actPasteMove.Click += new EventHandler(actPasteMove_Click);
		actPasteCopy.Click += new EventHandler(actPasteCopy_Click);
		actPasteCopyChild.Click += new EventHandler(actPasteCopyChild_Click);
		
		actCheckout.Attributes.Add("onclick", "return confirmCheckout();");
		actDelete.Attributes.Add("onclick", "return confirmDelete();");
	}
	#endregion
	#region Data Binding
	/// <summary>
	/// Rebind the data 
	/// </summary>
	protected void BindData()
	{
		ContentManager cms = new ContentManager();
		ContentObject o = cms.AdxGetByID(ContentID);
		if (o == null)
		{
			ContentID = -1;
			this.txtContentName.Text = "root";
			this.txtContentPath.Text = "/";
			this.txtContentID.Text = "N/A";
			this.txtStatus.Text = "N/A";

			// Setup root button states
			SetButtonStateRoot();
		}
		else
		{
			this.txtContentName.Text = o.NodeTitle;
			this.txtContentPath.Text = o.NodePath + o.NodeName + ".aspx";
			this.txtContentID.Text = o.PK_ID.ToString();
			this.txtStatus.Text = o.EnhancedStatusText(CurrentUser);
			SetButtonState(o.EnhancedStatus(CurrentUser));
		}

	}
	/// <summary>
	/// Sets the availability of the various action buttons based on 
	/// the state of the content item as passed in.
	/// </summary>
	/// <param name="stat"></param>
	protected void SetButtonState(ContentObjectEnhancedStatus state)
	{
		actAddNew.Enabled = true;

		actEdit.Enabled = (state == ContentObjectEnhancedStatus.CHECKEDOUTME);

		actDelete.Enabled = (state == ContentObjectEnhancedStatus.CHECKEDOUTME);

		actCheckout.Enabled = ((state != ContentObjectEnhancedStatus.CHECKEDOUT) &&
										(state != ContentObjectEnhancedStatus.CHECKEDOUTME));

		actCheckin.Enabled = (state == ContentObjectEnhancedStatus.CHECKEDOUTME);

		actSubmit.Enabled = ((state == ContentObjectEnhancedStatus.CHECKEDINAWAITING) ||
										(state == ContentObjectEnhancedStatus.CHECKEDINAWAITINGME));

		actMoveUp.Enabled = true;

		actMoveDown.Enabled = true;

		// Version history is only available if state isn't checked out or if it's checked out to me
		actVersionHistory.Enabled = ((state == ContentObjectEnhancedStatus.COMPLETE) ||
									 (state == ContentObjectEnhancedStatus.CHECKEDOUTME ));

		actCopy.Enabled = true;
		SetClipboardButtons();
	}
	/// <summary>
	/// Sets the availability of the various action buttons based
	/// on the root node being selected.
	/// </summary>
	protected void SetButtonStateRoot()
	{
		actAddNew.Enabled = true;
		actEdit.Enabled = false;
		actDelete.Enabled = false;
		actCheckout.Enabled = false;
		actCheckin.Enabled = false;
		actSubmit.Enabled = false;
		actMoveUp.Enabled = false;
		actMoveDown.Enabled = false;
		actVersionHistory.Enabled = false;
		actCopy.Enabled = false;
		SetClipboardButtons();
	}
	/// <summary>
	/// Gets the content object on the CMS Clipboard
	/// </summary>
	/// <returns></returns>
	protected ContentObject GetClipboardObject()
	{
		ContentObject clipboard = null;
		ContentManager cms = new ContentManager();
		object o = Session["CMS_Clipboard"];
		if (o != null)
		{
			int nid = (int)o;
			clipboard = cms.AdxGetByID(nid);
		}

		return clipboard;
	}
	/// <summary>
	/// Determines if a paste move or paste copy with children operation 
	/// can be performed. Operation cannot be performed where the node
	/// would be moved into a child or itself. Same applies to child operation
	/// as the copy would iterate over itself continually..
	/// </summary>
	/// <returns></returns>
	protected bool CanPasteMove()
	{
		bool EnablePasteMove = false;
		// Can always move into the root node
		if (this.ContentID == -1) EnablePasteMove = true;
		else
		{
			ContentManager cms = new ContentManager();
			ContentObject clipboard = this.GetClipboardObject();
			if( clipboard == null ) return false;

			ContentObject target = cms.AdxGetByID(this.ContentID);
			string TargetPath = target.NodePath + target.NodeName;
			string SourcePath = clipboard.NodePath + clipboard.NodeName;
			if( TargetPath.StartsWith( SourcePath )) EnablePasteMove = false;
			else EnablePasteMove = true;
		}
		return EnablePasteMove;
	}
	/// <summary>
	/// Determines if the clipboard buttons should be enabled or not
	/// </summary>
	protected void SetClipboardButtons()
	{
		ContentObject clipboard = GetClipboardObject();

		if (clipboard == null)
		{
			actPasteMove.Enabled = false;
			actPasteCopy.Enabled = false;
			actPasteCopyChild.Enabled = false;
		}
		else
		{
			actPasteMove.Enabled = CanPasteMove();
			actPasteCopy.Enabled = true;
			actPasteCopyChild.Enabled = actPasteMove.Enabled;

			actPasteMove.Text = String.Format("Paste Move ({0})", clipboard.NodeName);
			actPasteCopy.Text = String.Format("Paste Copy ({0})", clipboard.NodeName);
			actPasteCopyChild.Text = String.Format("Paste Copy with Children ({0})", clipboard.NodeName);
		}
	}
	#endregion
	#region Utility Methods
	/// <summary>
	/// Utility function to ask the content and content tree frames to refresh
	/// </summary>
	protected void ReloadFrames()
	{
		ClientScript.RegisterStartupScript(typeof(Private_CMS_main_actions),
			"treerefresh",
			"this.parent.refreshTree();", true);

		ClientScript.RegisterStartupScript(typeof(Private_CMS_main_actions),
			"listrefresh",
			"this.parent.refreshContent();", true);
	}
	/// <summary>
	/// Loads the specified URL into
	/// </summary>
	/// <param name="url"></param>
	protected void ContentLoad(string url)
	{
		ClientScript.RegisterStartupScript(typeof(Private_CMS_main_actions),
			"actionload",
			String.Format("this.parent.loadForm('{0}');", Page.ResolveUrl(url)),
			true);
	}
	/// <summary>
	/// Gets the URL for the a content form
	/// </summary>
	/// <param name="form"></param>
	protected string GetEditForm(string form)
	{
		string url = String.Format("{0}{1}&ContentID={2}",
			form,
			form.Contains("?") ? "" : "?",
			ContentID);

		return url;
	}
	#endregion
	#region Interaction Handlers
	/// <summary>
	/// User has clicked the add new button - present UI
	/// to choose what content type to add as a child of
	/// the currently selected node.
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	void actAddNew_Click(object sender, EventArgs e)
	{
		ContentLoad(String.Format(
			"~/admin/private/cms/main/actions/addnew/selectType.aspx?ParentID={0}",
			this.ContentID));
	}
	/// <summary>
	/// User has clicked the edit button - present the UI
	/// edit form for the content type of this selected node.
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	void actEdit_Click(object sender, EventArgs e)
	{
		ContentManager cms = new ContentManager();
		ContentObject o = cms.AdxGetByID( this.ContentID );
		if( o == null ) return;
		if( o.TypeTemplate == null ) return;

		ContentLoad( GetEditForm( o.TypeTemplate.EditForm ) );
	}
	/// <summary>
	/// Checkin the currently selected item. Presents a UI
	/// to capture version history notes to store in 
	/// the database. If no workflow is available from here,
	/// then automatically submit to publishing.
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	void actCheckin_Click(object sender, EventArgs e)
	{
		ContentLoad( String.Format(
			"~/admin/private/cms/main/actions/checkin/getnotes.aspx?ContentID={0}",
			this.ContentID));
	}
	/// <summary>
	/// Checkout the currently selected item to the current user
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	void actCheckout_Click(object sender, EventArgs e)
	{
		// Checkout the content
		ContentManager cms = new ContentManager();
		ContentObject o = cms.AdxGetByID( ContentID );
		if (o != null)
		{
			cms.CheckOut(ContentID, CurrentUser.PK_ID);

			// Audit
			Deepcode.Flux.Core.Systems.Audit.Quick.QuickAudit.RaiseInformation(new Deepcode.Flux.Core.Systems.Audit.Quick.AuditUser(),
				"Flux",
				"Content Manager",
				"checked out {0}", o.NodeTitle);
		}

		// Refresh the other frames to reflect the change
		ReloadFrames();
		// Rebind the button states etc
		BindData();
	}
	/// <summary>
	/// Submit the content item to publishing. If no workflow is
	/// available, automatically publish. If there is workflow, present
	/// the UI to choose which workflow to submit through.
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	void actSubmit_Click(object sender, EventArgs e)
	{
		ContentLoad(String.Format(
			"~/admin/private/cms/main/actions/submit/choosedef.aspx?ContentID={0}",
			this.ContentID));
	}
	/// <summary>
	/// Delete the content item from the database
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	void actDelete_Click(object sender, EventArgs e)
	{
		// Load the content
		ContentManager cms = new ContentManager();
		ContentObject obj = cms.AdxGetByID( this.ContentID );

		if (obj != null)
		{
			// Delete the content
			cms.Delete(this.ContentID);

			// Audit
			Deepcode.Flux.Core.Systems.Audit.Quick.QuickAudit.RaiseImportant(new Deepcode.Flux.Core.Systems.Audit.Quick.AuditUser(),
				"Flux",
				"Content Manager",
				"deleted {0}", obj.NodeTitle);

			// Change the selected ID to the parent
			ContentID = obj.FK_ParentID;
		}
		// Refresh the other frames to reflect the change
		ReloadFrames();

		// Rebind the button states etc
		BindData();
	}
	/// <summary>
	/// Move the content item up in rank
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	void actMoveUp_Click(object sender, EventArgs e)
	{
		// Shuffle the content
		ContentManager cms = new ContentManager();
		cms.RankUp( this.ContentID );

		// Refresh the other frames to reflect the change
		ReloadFrames();
		
		// Rebind the button states etc
		BindData();
	}
	/// <summary>
	/// Move the content item down in rank
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	void actMoveDown_Click(object sender, EventArgs e)
	{
		// Shuffle the content
		ContentManager cms = new ContentManager();
		cms.RankDown(this.ContentID);

		// Refresh the other frames to reflect the change
		ReloadFrames();

		// Rebind the button states etc
		BindData();
	}
	/// <summary>
	/// Display version history UI
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	void actVersionHistory_Click(object sender, EventArgs e)
	{
		ContentLoad(String.Format(
			"~/admin/private/cms/main/actions/history/viewhistory.aspx?ContentID={0}",
			this.ContentID));
	}
	/// <summary>
	/// Copy the node to the clipboard
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	void actCopy_Click(object sender, EventArgs e)
	{
		Session["CMS_Clipboard"] = this.ContentID;
		BindData();
	}
	/// <summary>
	/// Reparent the node
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	void actPasteMove_Click(object sender, EventArgs e)
	{
		if( ! CanPasteMove() ) return;

		// Get the clipboard object, if valid
		ContentManager cms = new ContentManager();
		ContentObject clipboard = GetClipboardObject();
		if( clipboard == null ) return;

		// Move it using the cms object
		cms.MoveParent( clipboard.PK_ID, this.ContentID );

		// Rebind
		ReloadFrames();
		BindData();
	}
	/// <summary>
	/// Paste a single CMS node copy
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	void actPasteCopy_Click(object sender, EventArgs e)
	{
		ContentManager cms = new ContentManager();
		ContentObject clipboard = GetClipboardObject();
		ContentObject target = cms.AdxGetByID( this.ContentID );
		if( clipboard == null ) return;
		if( this.ContentID != -1 && target == null ) return;
	
		ContentObject newitem = new ContentObject( clipboard, this.ContentID, CurrentUser.PK_ID );
		cms.Save( newitem, this.CurrentUser.PK_ID );

		ReloadFrames();
		BindData();
	}
	/// <summary>
	/// Paste a copy of the source node and all of it's children
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	void actPasteCopyChild_Click(object sender, EventArgs e)
	{
		if( ! CanPasteMove() ) return;

		ContentManager cms = new ContentManager();
		ContentObject clipboard = GetClipboardObject();
		ContentObject target = cms.AdxGetByID( this.ContentID );
		if( clipboard == null ) return;
		if( this.ContentID != -1 && target == null ) return;

		// Copy recursively
		RecursiveCopy( clipboard, this.ContentID, ref cms );
		
		ReloadFrames();
		BindData();
	}
	/// <summary>
	/// Recursively copies nodes
	/// </summary>
	/// <param name="source"></param>
	/// <param name="ParentID"></param>
	/// <param name="cms"></param>
	void RecursiveCopy(ContentObject source, int ParentID, ref ContentManager cms)
	{
		ContentObject copy = new ContentObject( source, ParentID, CurrentUser.PK_ID );
		copy = cms.Save( copy, CurrentUser.PK_ID );

		foreach (ContentObject child in source.ChildrenStaging)
			RecursiveCopy( child, copy.PK_ID, ref cms );
	}
	#endregion
}
